package com.xingfudazi.app.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xingfudazi.app.domain.AppAct;
import com.xingfudazi.app.domain.AppActSign;
import com.xingfudazi.app.mapper.AppActMapper;
import com.xingfudazi.app.service.IAppActService;
import com.xingfudazi.app.service.IAppActSignService;
import com.xingfudazi.common.exception.ServiceException;
import com.xingfudazi.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author YuJiaMing
 * date 2024年09月20日 00:18
 */
@Service
public class AppActServiceImpl extends ServiceImpl<AppActMapper, AppAct> implements IAppActService {

    @Autowired
    private IAppActSignService appActSignService;

    @Override
    public List<AppAct> selectList(AppAct appAct) {
        if (appAct == null) {
            appAct = new AppAct();
        }

        LambdaQueryWrapper<AppAct> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(appAct.getCategory()), AppAct::getCategory, appAct.getCategory());
        wrapper.orderByDesc(AppAct::getActTime);

        return this.list(wrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void sign(AppActSign appActSign) {
        Long actId = appActSign.getActId();
        Long nid = appActSign.getNid();

        if (actId == null || nid == null) {
            throw new IllegalArgumentException();
        }

        // AppAct appAct = this.getById(actId);
        // 校验现在的人数是否充足
        // validateSignLimit(appAct, appActSign.getSignNumber());


        // 查询是否已经报名了
        LambdaQueryWrapper<AppActSign> signWrapper = new LambdaQueryWrapper<>();
        signWrapper.eq(AppActSign::getActId, actId);
        signWrapper.eq(AppActSign::getNid, nid);
        if (this.appActSignService.count(signWrapper) > 0) {
            throw new ServiceException("已经报名了");
        }


        // 记录报名
        appActSign.setStatus(AppActSign.PENDING);
        this.appActSignService.save(appActSign);

    }


    @Override
    public void signCheck(AppActSign appActSign) {
        // 同步方法
        // synchronized (this) {
        //     // 二次查询、注意事物隔离问题
        //     appAct = this.getNewById(actId);
        //
        //     // 双重校验
        //     validateSignLimit(appAct, appActSign.getSignNumber());
        //
        //     // 减库存
        //     AppAct updateAct = AppAct.builder().actId(actId).signNumber(appAct.getSignNumber() + appActSign.getSignNumber())
        //             .build();
        //     this.updateById(updateAct);
        //
        //     // 记录报名
        //     appActSign.setStatus(AppActSign.PENDING);
        //     this.appActSignService.save(appActSign);
        // }

        this.appActSignService.updateById(appActSign);

        if (appActSign.getStatus().equals(AppActSign.SUCCESS)) {
            Long actId = appActSign.getActId();
            AppAct appAct = this.getNewById(actId);
            AppAct updateAct = AppAct.builder().actId(actId).signNumber(appAct.getSignNumber() + appActSign.getSignNumber())
                    .build();
            this.updateById(updateAct);
        }

    }

    @Transactional(propagation = Propagation.NEVER)
    private AppAct getNewById(Long actId) {
        return this.getById(actId);
    }

    private void validateSignLimit(AppAct appAct, Integer signNumber) {
        if ((appAct.getNumberLimit() - appAct.getSignNumber()) >= signNumber) {
            return;
        }

        throw new ServiceException("报名人数不足够支撑");
    }


    public static void main(String[] args) {
        System.out.println(System.currentTimeMillis());
    }
}
